package com.lb.ai.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;

/**
 * 链式调用风格的邮件工具类
 * 继承自EmailUtils，支持所有原有功能，并提供链式调用方式
 * 
 * 使用示例：
 * <pre>
 * {@code
 * // 简单邮件发送
 * ChainEmailUtils.create()
 *     .to("user@example.com")
 *     .subject("测试邮件")
 *     .content("邮件内容")
 *     .send();
 * 
 * // 复杂邮件发送
 * ChainEmailUtils.create()
 *     .to("user@example.com")
 *     .subject("测试邮件")
 *     .htmlContent("<h1>标题</h1><p>内容</p><img src='cid:img1'>")
 *     .addAttachment(new File("文档.pdf"), "报告.pdf")
 *     .addInlineImage("img1", new File("图片.jpg"))
 *     .send();
 * }
 * </pre>
 *
 * @author LiuB
 * @version 1.0
 * @see EmailUtils
 */
@Slf4j
@Component
public class ChainEmailUtils extends EmailUtils {

    /** 单个收件人邮箱地址 */
    private String to;
    
    /** 批量收件人邮箱地址列表 */
    private List<String> toList;
    
    /** 邮件主题 */
    private String subject;
    
    /** 邮件内容 */
    private String content;
    
    /** 是否为HTML内容 */
    private boolean isHtml = false;
    
    /** 模板名称 */
    private String templateName;
    
    /** 模板变量 */
    private Map<String, Object> templateVariables;
    
    /** 附件Map，key为文件对象，value为自定义的附件名 */
    private Map<File, String> attachments;
    
    /** 内联图片Map，key为图片ID（对应content中的cid），value为图片文件 */
    private Map<String, File> inlineImages;

    /**
     * 创建ChainEmailUtils实例
     * 
     * @return ChainEmailUtils实例
     */
    public static ChainEmailUtils create() {
        return new ChainEmailUtils();
    }

    /**
     * 设置单个收件人邮箱地址
     * 
     * @param to 收件人邮箱地址
     * @return 当前实例
     * @throws IllegalArgumentException 如果邮箱地址为空
     */
    public ChainEmailUtils to(String to) {
        if (to == null || to.trim().isEmpty()) {
            throw new IllegalArgumentException("收件人邮箱地址不能为空");
        }
        this.to = to;
        return this;
    }

    /**
     * 设置多个收件人邮箱地址
     * 
     * @param toList 收件人邮箱地址列表
     * @return 当前实例
     * @throws IllegalArgumentException 如果邮箱地址列表为空
     */
    public ChainEmailUtils to(List<String> toList) {
        if (toList == null || toList.isEmpty()) {
            throw new IllegalArgumentException("收件人邮箱地址列表不能为空");
        }
        this.toList = toList;
        return this;
    }

    /**
     * 设置邮件主题
     * 
     * @param subject 邮件主题
     * @return 当前实例
     * @throws IllegalArgumentException 如果主题为空
     */
    public ChainEmailUtils subject(String subject) {
        if (subject == null || subject.trim().isEmpty()) {
            throw new IllegalArgumentException("邮件主题不能为空");
        }
        this.subject = subject;
        return this;
    }

    /**
     * 设置普通文本内容
     * 
     * @param content 邮件内容
     * @return 当前实例
     * @throws IllegalArgumentException 如果内容为空
     */
    public ChainEmailUtils content(String content) {
        if (content == null || content.trim().isEmpty()) {
            throw new IllegalArgumentException("邮件内容不能为空");
        }
        this.content = content;
        return this;
    }

    /**
     * 设置HTML格式的内容
     * 
     * @param htmlContent HTML格式的邮件内容
     * @return 当前实例
     * @throws IllegalArgumentException 如果HTML内容为空
     */
    public ChainEmailUtils htmlContent(String htmlContent) {
        if (htmlContent == null || htmlContent.trim().isEmpty()) {
            throw new IllegalArgumentException("HTML内容不能为空");
        }
        this.content = htmlContent;
        this.isHtml = true;
        return this;
    }

    /**
     * 设置邮件模板和变量
     * 
     * @param templateName 模板名称
     * @param variables 模板变量
     * @return 当前实例
     * @throws IllegalArgumentException 如果模板名称为空
     */
    public ChainEmailUtils template(String templateName, Map<String, Object> variables) {
        if (templateName == null || templateName.trim().isEmpty()) {
            throw new IllegalArgumentException("模板名称不能为空");
        }
        this.templateName = templateName;
        this.templateVariables = variables != null ? variables : new HashMap<>();
        this.isHtml = true;
        return this;
    }

    /**
     * 添加单个附件
     * 
     * @param file 附件文件
     * @param fileName 自定义的附件名称
     * @return 当前实例
     * @throws IllegalArgumentException 如果文件为空或不存在
     */
    public ChainEmailUtils addAttachment(File file, String fileName) {
        if (file == null || !file.exists()) {
            throw new IllegalArgumentException("附件文件不能为空或不存在");
        }
        if (fileName == null || fileName.trim().isEmpty()) {
            fileName = file.getName();
        }
        if (attachments == null) {
            attachments = new HashMap<>();
        }
        attachments.put(file, fileName);
        return this;
    }

    /**
     * 批量添加附件
     * 
     * @param attachments 附件Map，key为文件对象，value为自定义的附件名
     * @return 当前实例
     * @throws IllegalArgumentException 如果附件Map为空
     */
    public ChainEmailUtils addAttachments(Map<File, String> attachments) {
        if (attachments == null || attachments.isEmpty()) {
            throw new IllegalArgumentException("附件Map不能为空");
        }
        if (this.attachments == null) {
            this.attachments = new HashMap<>();
        }
        this.attachments.putAll(attachments);
        return this;
    }

    /**
     * 添加内联图片
     * 图片将在邮件正文中显示，而不是作为附件
     * 
     * @param imageId 图片ID，在HTML中通过 cid:imageId 引用
     * @param imageFile 图片文件
     * @return 当前实例
     * @throws IllegalArgumentException 如果图片ID为空或图片文件不存在
     */
    public ChainEmailUtils addInlineImage(String imageId, File imageFile) {
        if (imageId == null || imageId.trim().isEmpty()) {
            throw new IllegalArgumentException("图片ID不能为空");
        }
        if (imageFile == null || !imageFile.exists()) {
            throw new IllegalArgumentException("图片文件不能为空或不存在");
        }
        if (inlineImages == null) {
            inlineImages = new HashMap<>();
        }
        inlineImages.put(imageId, imageFile);
        return this;
    }

    /**
     * 批量添加内联图片
     * 
     * @param images 图片Map，key为图片ID，value为图片文件
     * @return 当前实例
     * @throws IllegalArgumentException 如果图片Map为空
     */
    public ChainEmailUtils addInlineImages(Map<String, File> images) {
        if (images == null || images.isEmpty()) {
            throw new IllegalArgumentException("图片Map不能为空");
        }
        if (this.inlineImages == null) {
            this.inlineImages = new HashMap<>();
        }
        this.inlineImages.putAll(images);
        return this;
    }

    /**
     * 发送邮件
     * 根据设置的参数自动选择合适的发送方式：
     * 1. 如果设置了多个收件人，自动使用批量发送
     * 2. 如果设置了模板，使用模板发送
     * 3. 如果同时有附件和图片，使用复合邮件发送
     * 4. 如果只有附件，使用附件邮件发送
     * 5. 如果只有图片，使用内联图片邮件发送
     * 6. 如果是HTML内容，使用HTML邮件发送
     * 7. 默认使用简单文本邮件发送
     *
     * @return 发送结果，true表示发送成功，false表示发送失败
     * @throws IllegalArgumentException 如果必要的参数缺失
     */
    public boolean send() {
        validateBasicParams();

        // 如果是批量发送
        if (toList != null && !toList.isEmpty()) {
            return sendBatch() > 0;
        }

        // 如果使用模板
        if (templateName != null) {
            return sendTemplateEmail(to, subject, templateName, templateVariables);
        }

        // 如果同时有附件和图片
        if (hasAttachments() && hasInlineImages()) {
            return sendBatchComplexEmail(Collections.singletonList(to), subject, content, 
                    inlineImages, attachments) > 0;
        }

        // 如果只有附件
        if (hasAttachments()) {
            return sendAttachmentsEmail(to, subject, content, attachments);
        }

        // 如果只有图片
        if (hasInlineImages()) {
            return sendInlineImageEmail(to, subject, content, inlineImages);
        }

        // 如果是HTML内容
        if (isHtml) {
            return sendHtmlEmail(to, subject, content);
        }

        // 默认发送简单文本邮件
        return sendSimpleEmail(to, subject, content);
    }

    /**
     * 批量发送邮件
     * 根据设置的参数自动选择合适的批量发送方式
     * 支持所有send()方法的发送方式，但针对多个收件人
     *
     * @return 发送成功的数量
     * @throws IllegalArgumentException 如果必要的参数缺失或收件人列表为空
     */
    public int sendBatch() {
        validateBasicParams();
        validateToList();

        // 如果使用模板
        if (templateName != null) {
            return sendBatchTemplateEmail(toList, subject, templateName, templateVariables);
        }

        // 如果同时有附件和图片
        if (hasAttachments() && hasInlineImages()) {
            return sendBatchComplexEmail(toList, subject, content, inlineImages, attachments);
        }

        // 如果只有附件
        if (hasAttachments()) {
            return sendBatchAttachmentsEmail(toList, subject, content, attachments);
        }

        // 如果只有图片
        if (hasInlineImages()) {
            return sendBatchInlineImageEmail(toList, subject, content, inlineImages);
        }

        // 如果是HTML内容
        if (isHtml) {
            return sendBatchHtmlEmail(toList, subject, content);
        }

        // 默认批量发送简单文本邮件
        return sendBatchSimpleEmail(toList, subject, content);
    }

    /**
     * 验证基本参数是否完整
     * 
     * @throws IllegalArgumentException 如果必要的参数缺失
     */
    private void validateBasicParams() {
        if ((to == null || to.isEmpty()) && (toList == null || toList.isEmpty())) {
            throw new IllegalArgumentException("收件人不能为空");
        }
        if (subject == null || subject.isEmpty()) {
            throw new IllegalArgumentException("邮件主题不能为空");
        }
        if (content == null && templateName == null) {
            throw new IllegalArgumentException("邮件内容和模板名称不能同时为空");
        }
    }

    /**
     * 验证收件人列表是否有效
     * 
     * @throws IllegalArgumentException 如果收件人列表为空
     */
    private void validateToList() {
        if (toList == null || toList.isEmpty()) {
            throw new IllegalArgumentException("批量发送时收件人列表不能为空");
        }
    }

    /**
     * 检查是否有附件
     * 
     * @return true表示有附件，false表示没有附件
     */
    private boolean hasAttachments() {
        return attachments != null && !attachments.isEmpty();
    }

    /**
     * 检查是否有内联图片
     * 
     * @return true表示有内联图片，false表示没有内联图片
     */
    private boolean hasInlineImages() {
        return inlineImages != null && !inlineImages.isEmpty();
    }
} 